<!doctype html>
<script src="../../resources/ahem.js"></script>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script src="../assert_selection.js"></script>
<script>
// This tests that double-clicking a word that follows newline and span.
if (window.internals) {
     internals.settings.setSmartInsertDeleteEnabled(false);
     internals.settings.setSelectTrailingWhitespaceEnabled(true);
}

function doubleClick(selection) {
    if (!window.eventSender)
        throw 'This test requires eventSender.';
    const target = selection.document.querySelector('b');
    const [x, y] = target.offsetHeight > 15
        ? [
            selection.computeLeft(target.parentNode) + 5,
            selection.computeTop(target) + 15
          ]
        : [
            selection.computeLeft(target) + 45,
            selection.computeTop(target) + 5
          ];
    eventSender.leapForward(9999); // Reset mouse click
    eventSender.mouseMoveTo(x, y);
    eventSender.mouseDown();
    eventSender.leapForward(1);
    eventSender.mouseUp();
    eventSender.leapForward(50);
    eventSender.mouseDown();
    eventSender.leapForward(1);
    eventSender.mouseUp();
    if (!selection.window.getSelection().anchorNode)
      throw 'No selection';
}

function doTest(whiteSpace, title, input, expected) {
    const kStyle = [
      'font: 10px/10px Ahem;',
      'outline: none;',
      `white-space: ${whiteSpace};`,
      'width: 20ch;',
    ].join(' ');

    selection_test(
        `<div style="${kStyle}">${input}</div>`,
        doubleClick,
        `<div style="${kStyle}">${expected}</div>`,
        `${whiteSpace}: ${title}`);
    selection_test(
        `<div contenteditable style="${kStyle}">${input}</div>`,
        doubleClick,
        `<div contenteditable style="${kStyle}">${expected}</div>`,
        `${whiteSpace}: ${title} [editable]`);
}

doTest('normal', '1 minimum case',
    'abcd efgh ijkl mnop <b>select1</b>',
    'abcd efgh ijkl mnop <b>^select1|</b>');

// We may have to make EditorClient::isSelectTrailingWhitespaceEnabled false on
// DumpRenderTree to clarify cases...
doTest('normal', '2 with another word after the span',
    'abcd efgh ijkl mnop <b>select2</b> nottoselect',
    'abcd efgh ijkl mnop <b>^select2</b> |nottoselect');

doTest('normal', '3 use linebreak as word separator (outside element)',
    'abcd efgh ijkl mnop\n<b>select3</b>\nnottoselect',
    'abcd efgh ijkl mnop\n<b>^select3</b>\n|nottoselect');

doTest('normal', '4 use tab as word separator (outside element)',
    'abcd efgh ijkl mnop\t<b>select4</b>\tnottoselect',
    'abcd efgh ijkl mnop\t<b>^select4</b>\t|nottoselect');

doTest('normal', '5 use multiple whitespaces as word separator (outside element)',
    'abcd efgh ijkl mnop    <b>select5</b>    nottoselect',
    'abcd efgh ijkl mnop    <b>^select5</b> |   nottoselect');

doTest('normal', '6 use linebreak as word separator (inside element)',
    'abcd efgh ijkl mnop<b>\nselect6\n</b>nottoselect',
    'abcd efgh ijkl mnop<b>\n^select6\n|</b>nottoselect');

doTest('normal', '7 use tab as word separator (inside element)',
    'abcd efgh ijkl mnop<b>\tselect7\t</b>nottoselect',
    'abcd efgh ijkl mnop<b>\t^select7\t|</b>nottoselect');

doTest('normal', '8 use multiple whitespaces as word separator (inside element)',
    'abcd efgh ijkl mnop<b>    select8    </b>nottoselect',
    'abcd efgh ijkl mnop<b>    ^select8 |   </b>nottoselect');

doTest('normal', '9 with another word in same the span',
    'abcd efgh ijkl mnop <b>select9 not</b> notyet',
    'abcd efgh ijkl mnop <b>^select9 |not</b> notyet');

doTest('normal', '10 with another word before the span, in the same line',
    'abcd efgh ijkl mnop qrst <b>select10</b> notyet',
    'abcd efgh ijkl mnop qrst <b>^select10</b> |notyet');

doTest('normal', '11 a first half of word is inside b element',
    'abcd efgh ijkl mnop qrst <b>sel</b>ect11 notyet',
    'abcd efgh ijkl mnop qrst <b>^sel</b>ect11 |notyet');

// We choose selectHere12 instead select12 here because <b>ect12</b> would be
// too short to be clicked by |doubleClick()|.
doTest('normal', '12 a second half of word is inside b element',
    'abcd efgh ijkl mnop qrst uvwx yz123 sel<b>ectHere12</b> notyet',
    'abcd efgh ijkl mnop qrst uvwx yz123 ^sel<b>ectHere12</b> |notyet');

// white-space:pre
doTest('pre', '1 use linebreak as word separator (outside element)',
    'abcd efgh ijkl mnop\n<b>select1</b>',
    'abcd efgh ijkl mnop\n<b>^select1|</b>',
    'pre');

doTest('pre', '2 use tab as word separator (outside element)',
    'abcd efgh ijkl mnop\t<b>select2</b>\tnottoselect',
    'abcd efgh ijkl mnop\t<b>^select2</b>\t|nottoselect');

doTest('pre', '3 use multiple whitespaces as word separator (outside element)',
    'abcd efgh ijkl mnop    <b>select3</b>    nottoselect',
    'abcd efgh ijkl mnop    <b>^select3</b>    |nottoselect');

doTest('pre', '4 use linebreak as word separator (inside element)',
    'abcd efgh ijkl mnop<b>\nselect4\n</b>nottoselect',
    'abcd efgh ijkl mnop<b>\n^select4|\n</b>nottoselect');

doTest('pre', '5 use tab as word separator (inside element)',
    'abcd efgh ijkl mnop<b>\tselect5\t</b>nottoselect',
    'abcd efgh ijkl mnop<b>\t^select5\t|</b>nottoselect');

doTest('pre', '6 use multiple whitespaces as word separator (inside element)',
    'abcd efgh ijkl mnop<b>    select6    </b>nottoselect',
    'abcd efgh ijkl mnop<b>    ^select6    |</b>nottoselect');

// white-space: pre-wrwap
doTest('pre-wrwap', '1 use linebreak as word separator (outside element)',
    'abcd efgh ijkl mnop\n<b>select1</b>\nnottoselect',
    'abcd efgh ijkl mnop\n<b>^select1</b>\n|nottoselect');


doTest('pre-wrap', '2 use tab as word separator (outside element)',
    'abcd efgh ijkl mnop\t<b>select2</b>\tnottoselect',
    'abcd efgh ijkl mnop\t<b>^select2</b>\t|nottoselect');

doTest('pre-wrap', '3 use multiple whitespaces as word separator (outside element)',
    'abcd efgh ijkl mnop    <b>select3</b>    nottoselect',
    'abcd efgh ijkl mnop    <b>^select3</b>    |nottoselect');

doTest('pre-wrap', '4 use linebreak as word separator (inside element)',
    'abcd efgh ijkl mnop<b>\nselect4\n</b>nottoselect',
    'abcd efgh ijkl mnop<b>\n^select4|\n</b>nottoselect');

doTest('pre-wrap', '5 use tab as word separator (inside element)',
    'abcd efgh ijkl mnop<b>\tselect5\t</b>nottoselect',
    'abcd efgh ijkl mnop<b>\t^select5\t|</b>nottoselect');

doTest('pre-wrap', '6 use multiple whitespaces as word separator (inside element)',
    'abcd efgh ijkl mnop<b>    select6    </b>nottoselect',
    'abcd efgh ijkl mnop<b>    ^select6    |</b>nottoselect');

// white-space: pre-line
doTest('pre-line', '1 use linebreak as word separator (outside element)',
    'abcd efgh ijkl mnop\n<b>select1</b>\nnottoselect',
    'abcd efgh ijkl mnop\n<b>^select1|</b>\nnottoselect');

doTest('pre-line', '2 use tab as word separator (outside element)',
    'abcd efgh ijkl mnop\t<b>select2</b>\tnottoselect',
    'abcd efgh ijkl mnop\t<b>^select2</b>\t|nottoselect');

doTest('pre-line', '3 use multiple whitespaces as word separator (outside element)',
    'abcd efgh ijkl mnop    <b>select3</b>    nottoselect',
    'abcd efgh ijkl mnop    <b>^select3</b> |   nottoselect');

doTest('pre-line', '4 use linebreak as word separator (inside element)',
    'abcd efgh ijkl mnop<b>\nselect4\n</b>nottoselect',
    'abcd efgh ijkl mnop<b>\n^select4|\n</b>nottoselect');

doTest('pre-line', '5 use tab as word separator (inside element)',
    'abcd efgh ijkl mnop<b>\tselect5\t</b>nottoselect',
    'abcd efgh ijkl mnop<b>\t^select5\t|</b>nottoselect');

doTest('pre-line', '6 use multiple whitespaces as word separator (inside element)',
    'abcd efgh ijkl mnop<b>    select6    </b>nottoselect',
    'abcd efgh ijkl mnop<b>    ^select6 |   </b>nottoselect');

// white-space: nowrap
// Note: Although following cases have no line-breaks that had caused problem
// reported bug28036, we add these for comprehensiveness.

doTest('nowrap', '1 use linebreak as word separator (outside element)',
    'abcd efgh ijkl mnop\n<b>select1</b>\nnottoselect',
    'abcd efgh ijkl mnop\n<b>^select1</b>\n|nottoselect');

doTest('nowrap', '2 use tab as word separator (outside element)',
    'abcd efgh ijkl mnop\t<b>select2</b>\tnottoselect',
    'abcd efgh ijkl mnop\t<b>^select2</b>\t|nottoselect');

doTest('nowrap', '3 use multiple whitespaces as word separator (outside element)',
    'abcd efgh ijkl mnop    <b>select3</b>    nottoselect',
    'abcd efgh ijkl mnop    <b>^select3</b> |   nottoselect');

doTest('nowrap', '4 use linebreak as word separator (inside element)',
    'abcd efgh ijkl mnop<b>\nselect4\n</b>nottoselect',
    'abcd efgh ijkl mnop<b>\n^select4\n|</b>nottoselect');

doTest('nowrap', '5 use tab as word separator (inside element)',
    'abcd efgh ijkl mnop<b>\tselect5\t</b>nottoselect',
    'abcd efgh ijkl mnop<b>\t^select5\t|</b>nottoselect');

doTest('nowrap', '6 use multiple whitespaces as word separator (inside element)',
    'abcd efgh ijkl mnop<b>    select6    </b>nottoselect',
    'abcd efgh ijkl mnop<b>    ^select6 |   </b>nottoselect');

// cases for source-originated line-breaks with white-space: pre-* family
doTest('pre', 'source break',
    'abcd efgh ijkl mnop\n<b>select1</b>\nnottoselect',
    'abcd efgh ijkl mnop\n<b>^select1|</b>\nnottoselect');

doTest('pre-wrap', 'source break',
    'abcd efgh ijkl mnop\n<b>select1</b>\nnottoselect',
    'abcd efgh ijkl mnop\n<b>^select1|</b>\nnottoselect');

doTest('pre-line', 'source break',
    'abcd efgh ijkl mnop\n<b>select1</b>\nnottoselect',
    'abcd efgh ijkl mnop\n<b>^select1|</b>\nnottoselect');
</script>
